import React from "react";
import {Resizable} from 'react-resizable';

import './grid.scss';
import BaseComponent from "../BaseComponent";
import Grid from "./Grid";
import {Tooltip} from "antd";

/**
 * _autoCalScrollX:true,//是否自动计算滚动
 * _scrollXOffset:0,//偏移量
 * columns:[
 *      {
 *          _resizeable:true,//是否启用拉伸列
 *          ellipsis:true,//是否文字显示点点点
 *          _showTooltip:true,//是否显示提示
 *      }
 * ]
 *
 */
export default class ResizeGrid extends BaseComponent {

    constructor(props) {
        super(props);
        this.state = {columns: this.props.columns || []};
    }

    UNSAFE_componentWillReceiveProps(nextProps, nextContext) {
        if (this.props.columns !== nextProps.columns) {
            this.setState({columns: nextProps.columns});
        }
    }

    closeLoadingIndicator() {
        this.grid.closeLoadingIndicator();
    }

    showLoadingIndicator(text = '加载中...') {
        this.grid.showLoadingIndicator(text);
    }

    getCurPage() {
        return this.grid.getCurPage();
    }

    setData(data, {curPage, pageSize, totalCount} = {}) {
        this.grid.setData(data, {curPage, pageSize, totalCount});
    }

    getData() {
        return this.grid.getData();
    }

    getDataAt(index) {
        return this.grid.getDataAt(index);
    }

    handleResize = (indexLevels) => (e, {size}) => {
        this.setState(({columns}) => {
            const nextColumns = [...columns];
            let {resizeColumn, containerColumn} = this._getResizeColumn(nextColumns, indexLevels, 1);
            containerColumn[indexLevels[indexLevels.length - 1]] = {
                ...resizeColumn,
                width: size.width,
            };
            return {columns: nextColumns};
        });
    };

    _getResizeColumn(columns, indexLevels, level) {
        if (indexLevels.length === level) {
            return {resizeColumn: columns[indexLevels[level - 1]], containerColumn: columns};
        } else {
            return this._getResizeColumn(columns[indexLevels[level - 1]].children, indexLevels, level + 1);
        }
    }

    _resizeColumn(column, indexLevels) {
        let newColumn = {
            ...column
        };
        if (column.children) {
            newColumn.children = column.children.map((column, index) => {
                let _indexLevels = [];
                _indexLevels.push(...indexLevels);
                _indexLevels.push(index);
                return this._resizeColumn(column, _indexLevels);
            });
        } else {
            let _indexLevels = [];
            _indexLevels.push(...indexLevels);
            let {_resizeable, ellipsis, render} = column;
            if (_resizeable) {

                newColumn.onHeaderCell = (column) => ({
                    width: column.width,
                    onResize: this.handleResize(_indexLevels),
                });

                if (render) {
                    if (ellipsis) {
                        newColumn.render = (text, record, index) => {
                            let _row = render(text, record, index, column);
                            return this._getResizeableComponent(column, text, _row);
                        }
                    } else {
                        newColumn.render = (text, record, index) => {
                            return render(text, record, index, column);
                        }
                    }
                } else {
                    if (ellipsis) {
                        newColumn.render = (text) => {
                            return this._getResizeableComponent(column, text, text);
                        }
                    }
                }
            }
        }
        return newColumn;
    }

    _getResizeableComponent(column, tip, row) {
        let {_showTooltip} = column;
        if (_showTooltip) {
            return (
                <Tooltip placement="top" title={tip}>
                    <div className="react-resizable-ellipsis" style={({width: column.width})}>{row}</div>
                </Tooltip>
            );
        }
        return (
            <div className="react-resizable-ellipsis" style={({width: column.width})}>{row}</div>
        );
    }

    _calColumnsTotalWidth(columns) {
        let width = 0;
        columns.forEach((column) => {
            width += column.width || 0;
            if (column.children) {
                width += this._calColumnsTotalWidth(column.children)
            }
        });
        return width;
    }

    render() {
        const columns = this.state.columns.map((column, index) => {
            return this._resizeColumn(column, [index]);
        });

        let {_autoCalScrollX, scroll, _scrollXOffset = 0} = this.props;
        if (_autoCalScrollX) {
            let x = this._calColumnsTotalWidth(columns) + _scrollXOffset;
            scroll = {x: x};
        }

        let components = {
            header: {
                cell: ResizeableTitle,
            }
        };
        if (this.props.components) {
            components = {...this.props.components, ...components};
        }

        return (
            <Grid {...this.props}
                  ref={(o) => this.grid = o}
                  scroll={scroll}
                  className={`resize-grid ${this.props.className || ''}`}
                  columns={columns}
                  components={components}
            >
                {
                    this.props.children
                }
            </Grid>
        )
    }
}

const ResizeableTitle = props => {
    const {onResize, width, ...restProps} = props;

    if (!width) {
        return <th {...restProps} />;
    }

    return (
        <Resizable
            width={width}
            height={0}
            onResize={onResize}
            draggableOpts={({enableUserSelectHack: false})}
        >
            <th {...restProps} />
        </Resizable>
    );
};
